package com.yykj.common.util;

import org.springframework.util.StringUtils;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by chendg
 * on 2019/9/26 0026.
 */
public class IDCardUtil {

    private final static Map<Integer, String> provinceNum = new HashMap<>();
    private final static int[] PARITYBIT = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
    private final static int[] POWER_LIST = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
    private final static String dateExpression = "(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)$";

    static {
        provinceNum.put(11, "北京");
        provinceNum.put(12, "天津");
        provinceNum.put(13, "河北");
        provinceNum.put(14, "山西");
        provinceNum.put(15, "内蒙古");
        provinceNum.put(21, "辽宁");
        provinceNum.put(22, "吉林");
        provinceNum.put(23, "黑龙江");
        provinceNum.put(31, "上海");
        provinceNum.put(32, "江苏");
        provinceNum.put(33, "浙江");
        provinceNum.put(34, "安徽");
        provinceNum.put(35, "福建");
        provinceNum.put(36, "江西");
        provinceNum.put(37, "山东");
        provinceNum.put(41, "河南");
        provinceNum.put(42, "湖北");
        provinceNum.put(43, "湖南");
        provinceNum.put(44, "广东");
        provinceNum.put(45, "广西");
        provinceNum.put(46, "海南");
        provinceNum.put(50, "重庆");
        provinceNum.put(51, "四川");
        provinceNum.put(52, "贵州");
        provinceNum.put(53, "云南");
        provinceNum.put(54, "西藏");
        provinceNum.put(61, "陕西");
        provinceNum.put(62, "甘肃");
        provinceNum.put(63, "青海");
        provinceNum.put(64, "新疆");
        provinceNum.put(71, "台湾");
        provinceNum.put(81, "香港");
        provinceNum.put(82, "澳门");
        provinceNum.put(91, "外国");
    }


    public static boolean isIDCard(String certNo) {
        certNo = StringUtils.trimAllWhitespace(certNo);
        //身份证号是15位或者18位
        if (certNo.length() != 15 && certNo.length() != 18) {
            return false;
        }

        final char[] cs = certNo.toUpperCase().toCharArray();
        int power = 0;
        for (int i = 0; i < cs.length; i++) {
            if (i == cs.length - 1 && cs[i] == 'X') {
                break;//最后一位可以 是X或x
            }

            if (cs[i] < '0' || cs[i] > '9') {//除最后一位有非数字，则不是身份证号
                return false;
            }
            if (i < cs.length - 1) {
                power += (cs[i] - '0') * POWER_LIST[i];
            }

        }
        //18位身份证号最后一位是否正确,15位身份证没有该项校验
        if (certNo.length() != 15 && cs[cs.length - 1] != PARITYBIT[power % 11]) {
            return false;
        }

        //校验区位码 判断省份
        if (!provinceNum.containsKey(Integer.valueOf(certNo.substring(0, 2)))) {
            return false;
        }
        //居民身份证从1999年10月1日起，全国实行公民身份证号码制度，居民身份证编号由原15位升至18位。
        //所以现用15位身份证的都是19开头的,18开头的，最年轻的1899年的，120岁以上了，不做考虑
        //校验出生日期
        String birthdate = null;
        if (certNo.length() == 15) {
            birthdate = "19" + certNo.substring(6, 12);
        } else {
            birthdate = certNo.substring(6, 14);
        }
        return checkDate(birthdate);
    }

    private static boolean checkDate(String date) {
        int year = Integer.parseInt(date.substring(0, 4));
        int month = Integer.parseInt(date.substring(4, 6));
        int day = Integer.parseInt(date.substring(6, 8));
        if (date.matches(dateExpression)) {
            Calendar c = Calendar.getInstance();
            c.set(year, month - 1, day);
            if (year == c.get(Calendar.YEAR) && month - 1 == c.get(Calendar.MONTH) && day == c.get(Calendar.DATE)) {
                return true;
            }
        }
        return false;
    }

}
